Skip to content

Five readouts on the transport display, three of which catch a ruined recording - #52

Merged
revtex merged 1 commit into
mainfrom
record-transport-readouts
Sep 2, 2026
Merged

Five readouts on the transport display, three of which catch a ruined recording#52
revtex merged 1 commit into
mainfrom
record-transport-readouts

Conversation

@revtex

@revtex revtex commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Stacked on #51. Base is record-transport-fixes; merge that one first and this retargets to main on its own.

The display said what the file would be and how long it had been going. It said nothing about whether any of it was working, which is the question the Record page exists to answer.

What was added

SILENT lamp. Recording an hour of nothing is this app's signature failure — AudioLevelMeter's own remarks name it: audio routed to a device that is not being captured shows full volume in Windows and records nothing. The only symptom was a flat meter nobody was watching. The lamp appears after six seconds and counts how long the quiet has run. Six, because the gap between two tracks is silent and a warning that flashes up between every song is one nobody reads by the third time.

CLIP lamp. Latches when the audio reaches full scale during a track. Distortion is inaudible while you are not listening and permanent once encoded; the lamp clears when the next track starts, because what it latches is a fault in one file.

Capture device name, on the line that describes the file. It answers the question the silence lamp raises — the silent case is always the wrong endpoint — and previously meant leaving the page for Settings.

Running file size, for constant-bitrate formats only. FLAC and WAV are excluded rather than estimated: a FLAC's size depends on how compressible the music is, and a guess on this line would be wrong by a quarter either way.

STOPS IN countdown, whenever a recording timer is armed. It is set on the Advanced page and was then completely invisible on the page running it. Deliberately smaller than the elapsed clock — two readouts at the same size read as two equal answers, and this one is subordinate.

Both lamps are absent unless something is wrong, so the ordinary display is unchanged.

The constraint that shaped it

AudioLevelMeter.Read drains the interval it reports. Polling it for silence or clipping would have taken samples away from the bars, leaving the meter reading low by an amount that varied with how often each side happened to poll — a bug with no symptom on either side. Both flags are folded in on the capture thread inside Write instead, where every sample passes once and nothing is consumed.

Two things fell out of that:

  • Clipping must be tested on the peak sample, not on a reading. Everything this meter publishes is RMS, which sits ten to twenty decibels under the peak on real music — a lamp driven from LevelReading.Decibels would never have lit. There is a test asserting exactly that: a full-scale sample sets the flag while the RMS reading stays below −20 dBFS.
  • The clip threshold is 0.999, not 1.0. A converter out of headroom pins to the largest value the format holds, and 16-bit's 32767/32768 never normalises to exactly one. Testing for equality with full scale would miss every clipped integer recording.

The silence threshold is −80 dBFS rather than exact zero for the same class of reason: digital silence is zeroes, but a capture graph with any analogue stage idles on a dither floor, and calling that "not silent" would disable the warning on exactly the hardware that needs it.

Deliberately not covered: silence while waiting for a track

The silence lamp only arms once a track is actually being written. Offstream holds the capture
open through WAIT too, so the flag is available there — but silence while nothing is playing is
the normal state of that stage, and a lamp that lights every time the user presses Start before
starting Spotify is a lamp they learn to ignore. The case it would catch, a wrong endpoint that
also never detects a track, already announces itself: the transport sits on WAIT and no session
row ever appears. Once a track is detected the stage goes to REC regardless of what the audio
is doing, which is where the lamp takes over and where the accidental reproduction above happened.

One existing test changed

FormatText_IsPopulatedBeforeAnythingStarts asserted the whole line was upper case, which held while it was nothing but codes and numbers. It now covers the technical run only. The device name follows after a separator and keeps the capitalisation its maker gave it — shouting SPEAKERS (REALTEK(R) AUDIO) to preserve a rule about codes would make the one part of the line anyone actually reads the hardest to read.

Verification

  • .\build.ps1 -Test1,285 pass, 0 fail (271 UI + 1,014 Core), 0 warnings. 13 new tests.
  • .\build.ps1 -VerifyFormat — clean. en/fr key parity holds at 218 each.
  • Verified live, and by accident. A staged profile recording the default endpoint while Spotify played to VB-CABLE reproduced the exact failure the silence lamp exists for, and the lamp lit at six seconds over a completely flat meter. The same run showed MP3 320K 48K · Speakers (5- Cirrus Logic XU) · 0.7 MB and a STOPS IN 00:59:42 countdown against a one-hour timer. No recording was left behind and the real %APPDATA% profile was never written to — every run was under OFFSTREAM_HOME.

Docs: CHANGELOG.md (Added), README.md (the walkthrough plus two troubleshooting rows), a plan finding on the single-reader meter, and a CLAUDE.md rule so the next person does not add a second reader.

@revtex
revtex changed the base branch from record-transport-fixes to main September 2, 2026 17:22
… recording

The display said what the file would be and how long it had been going. It said
nothing about whether any of it was working, which is the question the page is
actually there to answer.

Recording an hour of silence is this app's signature failure. AudioLevelMeter's own
remarks name it — audio routed to a device that is not being captured shows full
volume in Windows and records nothing — and until now the only symptom was a flat
meter nobody was watching. A SILENT lamp appears after six seconds and counts how
long the quiet has run; six because the gap between two tracks is silent and a
warning that flashes up between every song is one nobody reads by the third time. A
CLIP lamp latches when the audio reaches full scale, because distortion is inaudible
while you are not listening and permanent once encoded. Both are absent unless
something is wrong, so the ordinary display is unchanged. The capture device's name
now sits on the line that describes the file, which is the question the silence lamp
raises and previously meant a trip to Settings to answer; the running size follows it
for constant-bitrate formats; and a STOPS IN countdown appears whenever a recording
timer is armed, which was set on Advanced and then wholly invisible on the page
running it.

The interesting constraint was where to detect any of it. Read drains the interval it
reports, so polling it for silence or clipping would have taken samples away from the
bars and left the meter reading low by an amount that varied with how often each side
polled — a bug with no symptom either side would show. Both flags are folded in on
the capture thread inside Write instead, where every sample passes once and nothing
is consumed. Two things fell out of that. Clipping has to be tested on the peak
sample, not on a reading: everything this meter publishes is RMS, which sits ten to
twenty decibels under the peak on real music, so a lamp driven from
LevelReading.Decibels would never have lit. And the threshold is 0.999 rather than
1.0, because a converter out of headroom pins to the largest value the format holds
and 16-bit's 32767/32768 never normalises to exactly one.

FormatText_IsPopulatedBeforeAnythingStarts asserted the whole line was upper case,
which held while it was nothing but codes and numbers. It now covers the technical
run only: the device name follows after a separator and keeps the capitalisation its
maker gave it, since shouting SPEAKERS (REALTEK(R) AUDIO) to preserve a rule about
codes would make the one part of the line anyone reads the hardest to read.
@revtex
revtex force-pushed the record-transport-readouts branch from 5cae1c1 to 3199269 Compare September 2, 2026 17:23
@revtex
revtex merged commit 51785db into main Sep 2, 2026
6 checks passed
@revtex
revtex deleted the record-transport-readouts branch September 2, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant